package com.smartstate.admin.biz.controller;

import cn.hutool.poi.excel.ExcelUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.support.ExcelTypeEnum;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;

import com.smartstate.admin.biz.entity.bo.Role;
import com.smartstate.admin.biz.entity.bo.User;
import com.smartstate.admin.biz.entity.dto.UserDto;
import com.smartstate.admin.biz.entity.dto.UserSearchDto;
import com.smartstate.admin.biz.entity.vo.UserExcelVo;
import com.smartstate.admin.biz.entity.vo.UserVo;
import com.smartstate.admin.biz.mapper.PermissionMapper;

import com.smartstate.admin.biz.service.RoleService;
import com.smartstate.admin.biz.service.UserService;
import com.smartstate.admin.biz.service.impl.PermissionServiceImpl;
import com.smartstate.admin.biz.util.UserUtils;
import com.smartstate.common.base.constants.BizConstants;
import com.smartstate.common.base.constants.GlobalsConstants;
import com.smartstate.common.base.dto.ExcelExportDto;
import com.smartstate.common.base.exception.CommonException;
import com.smartstate.common.base.httpResult.ResultCode;
import com.smartstate.common.base.httpResult.ResultVO;
import com.smartstate.common.base.httpResult.BaseController;


import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.lang3.StringUtils;

import javax.annotation.Resource;

import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import javax.validation.constraints.NotBlank;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/user")
@Api(tags = "用户管理")
@Validated
public class UserController extends BaseController {
    @Resource
    private UserService userService;
    @Resource
    private PermissionServiceImpl permissionService;
    @Resource
    private PermissionMapper permissionMapper;
    @Resource
    private RoleService roleService;

    /**
     * 内置    admin  id 3c6baf2e80a34e4ba97a9df031367dc6
     * 企业编号 sss id 3c6baf2e80a34e4ba97a9df031367dc6
     * 用户默认拥有所有权限
     */
    @GetMapping("/principal")
    @ApiOperation(value = "获取web用户信息")
    public ResultVO getPrincipal() {
        return ResultVO.success(userService.getPrincipal(this.getIpAddr()));
    }

    @GetMapping("/app/principal")
    @ApiOperation(value = "获取app用户信息")
    public ResultVO getAppPrincipal() {
        return ResultVO.success(userService.getAppPrincipal(this.getIpAddr()));
    }



    @GetMapping("/web")
    @ApiOperation(value = "用户信息分页")
    public ResultVO getUserList(@ModelAttribute UserSearchDto userSearchDto) {
        return ResultVO.success(userService.queryUserList(userSearchDto));
    }

    @GetMapping("/web/info/{id}")
    @ApiOperation(value = "根据用户id获取用户信息")
    public ResultVO getUserByUserId(@ApiParam("用户id") @PathVariable String id) {
        return ResultVO.success(userService.loadUserByUserId(id));
    }

    @GetMapping(value = "/web/check")
    @ApiOperation(value = "校验用户某属性值是否重复", notes = "校验用户某属性值是否重复")
    public ResultVO checkUserName(@ApiParam(value = "用户id", required = false) @RequestParam(required = false) String id
            , @ApiParam(value = "用户名称或手机号或用户昵称", required = true) @RequestParam String str
            , @ApiParam(value = "校验类型 1:用户名称 2:用户昵称 3:手机", required = true) @RequestParam Integer type) {
        Map<String, Object> map = null;
        boolean flag = false;
        switch (type) {
            case 1:
                map = userService.checkUserName(str, id);
                flag = (boolean) map.get("flag");
                break;
            case 2:
                map = userService.checkNickname(str, id);
                flag = (boolean) map.get("flag");
                break;
            case 3:
                map = userService.checkPhone(str, id);
                flag = (boolean) map.get("flag");
                break;
            default:
                break;
        }
        if (flag) {
            return ResultVO.success("成功");
        } else {
            String msg = (String) map.get("msg");
            return ResultVO.error(msg);
        }
    }

    @GetMapping("/web/judge/{id}")
    @ApiOperation(value = "判断用户原密码是否正确-后台管理用户管理", notes = "判断用户原密码是否正确-后台管理用户管理")
    public ResultVO judgePassword(@RequestParam String password, @ApiParam("用户id") @PathVariable String id) {
        if (StringUtils.isBlank(id)) {
            return ResultVO.error("id不能为空");
        }
        if (StringUtils.isBlank(password)) {
            return ResultVO.error("密码不能为空");
        }
        if (userService.judgePassword(id, password)) {
            return ResultVO.success("填写成功");
        } else {
            return ResultVO.error("填写正确的密码");
        }
    }

    @PostMapping("/web/add")
    @ApiOperation(value = "添加用户")
    public ResultVO saveUser(@RequestBody UserDto userDto) {
        return ResultVO.success(userService.saveUser(userDto));
    }

    //@SysLog("修改用户")
    @PutMapping("/web/update")
    @ApiOperation(value = "修改用户")
    public ResultVO updateUser(@RequestBody UserDto userDto) {
        if(userDto.getId().equals(BizConstants.supperAdminId)){
            return ResultVO.error("超级管理员不允许修改");
        }
        return ResultVO.success(userService.updateUser(userDto));
    }

    //@SysLog("修改密码")
    @PutMapping("/web/updatePassword")
    @ApiOperation(value = "修改用户密码", notes = "修改用户密码")
    public ResultVO updateWebPassword(@RequestBody UserDto userDto) {
        if(userDto.getId().equals(BizConstants.supperAdminId)){
            return ResultVO.error("超级管理员不允许修改");
        }
        if (StringUtils.isBlank(userDto.getId())) {
            return ResultVO.error("id不能为空");
        }
        if (StringUtils.isBlank(userDto.getPassword())) {
            return ResultVO.error("新密码不能为空");
        }
        userDto.setUpdatePassword(1);
        if (userService.updatePassword(userDto)) {
            return ResultVO.success("修改成功");
        } else {
            return ResultVO.error("修改失败");
        }
    }


    //@SysLog("重置密码")
    @PutMapping("/web/resetPassword")
    @ApiOperation(value = "重置用户密码", notes = "重置用户密码-123456")
    public ResultVO resetWebPassword(@RequestBody UserDto userDto) {
        if(userDto.getId().equals(BizConstants.supperAdminId)){
            return ResultVO.error("超级管理员不允许重置密码");
        }
        if (StringUtils.isBlank(userDto.getId())) {
            return ResultVO.error("id不能为空");
        }
        userDto.setPassword(GlobalsConstants.PASSWORD);
        userDto.setUpdatePassword(2);
        if (userService.updatePassword(userDto)) {
            return ResultVO.success("重置成功");
        } else {
            return ResultVO.error("重置失败");
        }
    }

    //@SysLog("分配用户角色")
    @PutMapping("/web/role")
    @ApiOperation(value = "分配用户角色", notes = "分配用户角色")
    public ResultVO updateWebRole(@RequestBody UserDto userDto) {
        if (StringUtils.isBlank(userDto.getId())) {
            return ResultVO.error("id不能为空");
        }
        if (StringUtils.isBlank(userDto.getRoleId())) {
            return ResultVO.error("角色id不能为空");
        }
        if (userService.updateRole(userDto)) {
            return ResultVO.success("修改成功");
        } else {
            return ResultVO.error("修改失败");
        }
    }

    //@SysLog("修改用户状态")
    @PutMapping("/web/status/{id}")
    @ApiOperation(value = "修改用户状态  0无效 1有效 ")
    public ResultVO updateStatus(@ApiParam("用户id") @PathVariable String id, @ApiParam("状态 0无效 1有效") Integer status) {
        if(id.equals(BizConstants.supperAdminId)){
            return ResultVO.error("超级管理员不允许修改状态");
        }
        return ResultVO.success(userService.updateStatus(id, status));
    }


    //@SysLog("删除用户")
    @DeleteMapping("/web/del/{id}")
    @ApiOperation(value = "根据用户id删除用户信息")
    public ResultVO deleteUser(@ApiParam("用户id") @PathVariable String id) {
        if(id.equals(BizConstants.supperAdminId)){
            return ResultVO.error("超级管理员不允许删除");
        }
        return ResultVO.success(userService.deleteUser(id));
    }

    //@SysLog("批量删除用户")
    @DeleteMapping(value = "/web/delBatch")
    @ApiOperation(value = "批量删除用户管理", notes = "批量删除用户管理")
    public ResultVO deleteBatchUser(@RequestBody @NotBlank  String ids) {
        List<String> idList = JSON.parseArray(((JSONArray) JSON.parseObject(ids).get("ids")).toJSONString(), String.class);
        if (userService.deleteBatchUser(idList)) {
            return ResultVO.success("批量删除成功");
        } else {
            return ResultVO.error("批量删除失败");
        }
    }

    @GetMapping("/info/{id}")
    @ApiOperation(value = "根据用户id获取用户信息")
    public ResultVO loadUserByUserId( @NotBlank @PathVariable String id) {
        return ResultVO.success(userService.loadUserByUserId(id));
    }

    @GetMapping("/api/list")
    @ApiOperation(value = "批量传入用户id获取用户信息")
    public ResultVO<List<UserVo>> loadUserByUserIds(@RequestParam("ids") List<String> ids) {
        return ResultVO.success(userService.selectBatchUser(ids));

    }

    @GetMapping("/web/list")
    @ApiOperation(value = "批量传入用户id获取用户信息")
    public ResultVO<List<UserVo>> getUserByUserIds(@RequestParam("ids") List<String> ids) {
        if (CollectionUtils.isEmpty(ids)){
            throw new CommonException(ResultCode.PARAMETER_ERROR);
        }
        return ResultVO.success(userService.selectBatchUser(ids));

    }

    @GetMapping("/web/all")
    @ApiOperation(value = "所有用户信息")
    public ResultVO<List<UserVo>> loadUserAll() {
        return ResultVO.success(userService.getUserAll());
    }

    @GetMapping("/api/all")
    @ApiOperation(value = "所有用户信息")
    public ResultVO<List<UserVo>> getUserAll() {
        return ResultVO.success(userService.getUserAll());
    }

    @GetMapping("/api/{username}")
    @ApiOperation(value = "根据username获取用户信息")
    public ResultVO<String> getUserByUserName(@PathVariable("username") String username) {
        String id = userService.getUserByUserName(username);
        if (StringUtils.isNotBlank(id)){
            return ResultVO.success(id);
        }
        return new ResultVO<>(ResultCode.RESOURCE_NOT_EXISTS);
    }

    @GetMapping("/exportExcel")
    @ApiOperation(value = "导出用户信息excel")
    public ResultVO exportExcel(HttpServletResponse response) throws IOException {
        setExcelRespProp(response, "用户信息列表");
        List<UserVo> userList = userService.getUserAll();
        List<UserExcelVo> userExcelVoList = userList.stream().map(user -> {
            Role roleByUserId = roleService.getRoleByUserId(user.getId());
            UserExcelVo userExcelVo = new UserExcelVo();
            if (roleByUserId != null) {
                userExcelVo.setRoleName(roleByUserId.getRoleName());
            }
            BeanUtils.copyProperties(user, userExcelVo);
            return userExcelVo;
        }).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(userExcelVoList) && userExcelVoList.size() < 0){
            return ResultVO.error("用户信息为空");
        }
        EasyExcel.write(response.getOutputStream())
                .head(UserExcelVo.class)
                .excelType(ExcelTypeEnum.XLSX)
                .sheet("用户信息列表")
                .doWrite(userExcelVoList);
        return ResultVO.success();
    }

    @GetMapping("/exportTemplate")
    @ApiOperation(value = "导出用户模板excel")
    public ResultVO exportTemplate(HttpServletResponse response) throws IOException {
        setExcelRespProp(response, "用户信息模板");
        ArrayList<UserExcelVo> userExcelVo = new ArrayList<>();
        userExcelVo.add(new UserExcelVo());
        EasyExcel.write(response.getOutputStream())
                .head(UserExcelVo.class)
                .excelType(ExcelTypeEnum.XLSX)
                .sheet("用户信息模板")
                .doWrite(userExcelVo);
        return ResultVO.success();
    }

    @PostMapping("/uploadExcel")
    @ApiOperation(value = "导入用户信息excel")
    public ResultVO uploadExcel(@RequestPart MultipartFile file) throws IOException {
        List<UserExcelVo> userExcelVoList = EasyExcel.read(file.getInputStream())
                .head(UserExcelVo.class)
                .sheet()
                .doReadSync();
        if (CollectionUtils.isEmpty(userExcelVoList) && userExcelVoList.size() < 0){
            return ResultVO.error("导入用户数据为空");
        }
        userExcelVoList.stream().forEach(userExcelVo -> {
            UserDto userDto = new UserDto();
            BeanUtils.copyProperties(userExcelVo,userDto);
            userDto.setPassword(GlobalsConstants.PASSWORD);
            if (userExcelVo.getRoleName()!= null){
                String roleId = roleService.getRoleIdByRoleName(userExcelVo.getRoleName());
                if (StringUtils.isNotBlank(roleId)){
                    userDto.setRoleId(roleId);
                }
            }
            try {
                userService.saveUser(userDto);
            } catch (Exception e) {
                throw new CommonException(userDto.getUsername()+":数据导入失败",1);
            }
        });

        return ResultVO.success("导入用户数据成功，初始密码123456");
    }


    /**
     * 设置excel下载响应头属性
     */
    private void setExcelRespProp(HttpServletResponse response, String rawFileName) throws UnsupportedEncodingException {
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        String fileName = URLEncoder.encode(rawFileName, "UTF-8").replaceAll("\\+", "%20");
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");
    }


}
